﻿using Corina.Commands;
using Corina.Common;
using Corina.Cydee.DataService;
using Corina.Datamodel.DataObject;
using Corina.Datamodel.Entities;
using Corina.Enumerations;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;

namespace Corina.Cydee.Apphub.Viewmodels
{
    public class DeviceSaleViewmodel : ViewmodelBase
    {
        public DeviceSaleViewmodel()
        {
            DeviceClient.GetAllDeviceSaleItemsCompleted += GetAllDeviceSaleItemsCompleted;
            DeviceClient.InsertDeviceSaleCompleted += InsertDeviceSaleCompleted;
            UserClient.GetAllUserItemsCompleted += GetAllUserItemsCompleted;
            DeviceClient.GetDeviceKindItemsCompleted += GetDeviceKindItemsCompleted;
            DeviceClient.GetDeviceItemsCompleted += GetDeviceItemsCompleted;
            DeviceClient.InsertDeviceSaleExtCompleted += InsertDeviceSaleCompleted;
            if (DataContext.IsValid)
            {
                LoadData();
                LoadRelatedData();
            }
        }

        #region Methods
        private void GetDeviceItemsCompleted(object sender, GetDeviceItemsCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result.Result == ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects.AsEnumerable()
                                 select new
                                 {
                                     Id = t["Id"],
                                     DeviceSn = (string)t["DeviceSn"],
                                     Kind = (string)t["Kind"],
                                     DataModule = (string)t["DataModule"],
                                     ManufactureDate = (DateTime)t["ManufactureDate"],
                                     RatePrice = t["RatePrice"]
                                 });
                    UnsaledDeviceCollection = new ObservableCollection<object>(items);
                    var _count = (e.Result.TotalCount + 19) / 20;
                    DevicePager = new ObservableCollection<int>(GetIEnumerable(_count));
                }
            }
        }

        private void GetDeviceKindItemsCompleted(object sender, DataService.GetDeviceKindItemsCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                DeviceKindCollection = new ObservableCollection<DeviceKindInfo>(e.Result.Entities.OfType<DeviceKindInfo>());
            }

        }

        private void GetAllUserItemsCompleted(object sender, DataService.GetAllUserItemsCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result.Result == ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects.AsEnumerable()
                                 select new
                                 {
                                     Id = t["Id"],
                                     Name = t["Name"],
                                     Account = t["Account"],
                                     UserLevel = string.IsNullOrEmpty(t["UserLevel"].ToString()) ? "未设置" : t["UserLevel"]
                                 });
                    UserCollection = new ObservableCollection<object>(items);
                    //ItemsCount = e.Result.TotalCount;
                    var _count = (e.Result.TotalCount + 19) / 20;
                    UserPager = new ObservableCollection<int>(GetIEnumerable(_count));
                }
            }
        }

        private void InsertDeviceSaleCompleted(object sender, EventArgs e)
        {
            Entities.Clear();
            Operation = EntityOperation.None;
            LoadData();
        }

        private void GetAllDeviceSaleItemsCompleted(object sender, DataService.GetAllDeviceSaleItemsCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result.Result == ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects
                                 select new
                                 {
                                     ItemIndex = t["ROW_NUMBER"],
                                     Id = t["Id"],
                                     DeviceSn = (string)t["DeviceSn"],
                                     Kind = (string)t["Kind"],
                                     ManufactureDate = t["ManufactureDate"],
                                     TransferKind = t["TransferKind"],
                                     Salesperson = t["Salesperson"],
                                     SaleDate = t["SaleDate"],
                                     Price = (double)t["Price"],
                                     UserName = (string)t["UserName"]
                                 });
                    ItemsCollection = new ObservableCollection<object>(items);
                    ItemsCount = e.Result.TotalCount;
                }
            }
            IsBusy = false;
        }

        protected override void LoadData(params object[] paras)
        {
            IsBusy = true;
            DeviceClient.GetAllDeviceSaleItemsAsync(Account, Password, DeviceSn, KindId, 0, Index, 20);
        }

        protected void LoadRelatedData()
        {
            //UserClient.GetAllUserItemsAsync(Account, Password, "", 1, 20);
            DeviceClient.GetDeviceKindItemsAsync();
        }

        private object GetObjectPropertyValue(object obj, string name)
        {
            Type t = obj.GetType();
            PropertyInfo p = t.GetProperty(name);
            object v = p.GetValue(obj, null);
            return v;
        }

        private IEnumerable<int> GetIEnumerable(int count)
        {
            for (var i = 1; i <= count; i++)
            {
                yield return i;
            }
        }
        #endregion

        #region Collection
        private ObservableCollection<DeviceKindInfo> _deviceKindCollection;
        public ObservableCollection<DeviceKindInfo> DeviceKindCollection
        {
            get { return _deviceKindCollection; }
            set
            {
                _deviceKindCollection = value;
                RaisePropertyChanged(() => DeviceKindCollection);
            }
        }

        private ObservableCollection<object> _userCollection;
        public ObservableCollection<object> UserCollection
        {
            get { return _userCollection; }
            set
            {
                _userCollection = value;
                RaisePropertyChanged(() => UserCollection);
            }
        }

        private ObservableCollection<object> _unsaledDeeviceCollection;
        public ObservableCollection<object> UnsaledDeviceCollection
        {
            get { return _unsaledDeeviceCollection; }
            set
            {
                _unsaledDeeviceCollection = value;
                RaisePropertyChanged(() => UnsaledDeviceCollection);
            }
        }

        private ObservableCollection<object> _itemsCollection;
        public ObservableCollection<object> ItemsCollection
        {
            get { return _itemsCollection; }
            set
            {
                _itemsCollection = value;
                RaisePropertyChanged(() => ItemsCollection);
            }
        }
        #endregion

        #region Search
        private string _deviceSn = string.Empty;
        public string DeviceSn
        {
            get { return _deviceSn; }
            set
            {
                _deviceSn = value;
                RaisePropertyChanged(() => DeviceSn);
            }
        }

        private int _userId = 0;
        public int UserId
        {
            get { return _userId; }
            set
            {
                _userId = value;
                RaisePropertyChanged(() => UserId);
            }
        }

        private DeviceKindInfo _selectedDeviceKind;
        public DeviceKindInfo SelectedDeviceKind
        {
            get { return _selectedDeviceKind; }
            set
            {
                _selectedDeviceKind = value;
                RaisePropertyChanged(() => SelectedDeviceKind);
                KindId = SelectedDeviceKind == null ? 0 : SelectedDeviceKind.Id;
            }
        }

        private int _kindId = 0;
        public int KindId
        {
            get { return _kindId; }
            set
            {
                _kindId = value;
                RaisePropertyChanged(() => KindId);
            }
        }
        #endregion

        #region Update
        private int _selectedUserId = 0;
        public int SelectedUserId
        {
            get { return _selectedUserId; }
            set
            {
                _selectedUserId = value;
                RaisePropertyChanged(() => SelectedUserId);
                Entities.ToList().ForEach(t =>
                {
                    t.UserId = SelectedUserId;
                });
                RaisePropertyChanged(() => SubmitCommand);
            }
        }

        private string _dragDeviceSn = string.Empty;
        public string DragDeviceSn
        {
            get { return _dragDeviceSn; }
            set
            {
                _dragDeviceSn = value;
                RaisePropertyChanged(() => DragDeviceSn);
            }
        }

        private ObservableCollection<DeviceSaleInfo> _entities = new ObservableCollection<DeviceSaleInfo>();
        public ObservableCollection<DeviceSaleInfo> Entities
        {
            get { return _entities; }
            set
            {
                _entities = value;
                RaisePropertyChanged(() => Entities);
                RaisePropertyChanged(() => SubmitCommand);
            }
        }

        private double _salePrice = 0;
        public double SalePrice
        {
            get { return _salePrice; }
            set
            {
                _salePrice = value;
                RaisePropertyChanged(() => SalePrice);
            }
        }

        private bool _showPriceInput = false;
        public bool ShowPriceInout
        {
            get { return _showPriceInput; }
            set
            {
                _showPriceInput = value;
                RaisePropertyChanged(() => ShowPriceInout);
            }
        }

        public ICommand SubmitPriceCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate {
                        if (SalePrice > 0)
                        {
                            Entities.Add(new DeviceSaleInfo() { DeviceSn = DragDeviceSn, Price = SalePrice, UserId = SelectedUserId });
                            
                            SalePrice = 0;
                            ShowPriceInout = false;

                            var item = UnsaledDeviceCollection.FirstOrDefault(t => GetObjectPropertyValue(t, "DeviceSn") == DragDeviceSn);
                            UnsaledDeviceCollection.Remove(item);

                            DragDeviceSn = string.Empty;

                            RaisePropertyChanged(() => SubmitCommand);
                        }
                    }
                };
            }
        }
        #endregion

        #region Commands
        public ICommand LoadCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        Index = 1;
                        LoadData();
                    }
                };
            }
        }

        public ICommand InsertCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate {
                        
                        DeviceClient.GetDeviceItemsAsync(0, "", -1, 1, 20);
                        UserClient.GetAllUserItemsAsync(Account, Password, "", 1, 20);
                        Operation = EntityOperation.Insert;
                    }
                };
            }
        }

        public ICommand CancelCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        Entities.Clear();
                        Operation = EntityOperation.None;
                    }
                };
            }
        }

        public ICommand SubmitCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return Entities.Count > 0 && SelectedUserId > 0; },
                    ExecuteCallback = delegate
                    {
                        string jsonString = JsonHelper.Stringify(Entities);
                        DeviceClient.InsertDeviceSaleExtAsync(Account, Password, jsonString);
                    }
                };
            }
        }

        public ICommand MouseLeftButtonDownCommand
        {
            get
            {
                return new DelegateCommand(t =>
                {
                    DragDeviceSn = (string)t;
                });
            }
        }
        #endregion

        #region Event
        public void UserSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox box = sender as ListBox;
            object obj = box.SelectedItem;
            SelectedUserId = obj == null ? 0 : (int)GetObjectPropertyValue(obj, "Id");
        }

        public void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            TextBlock listview = sender as TextBlock;
            //HitTestResult result = VisualTreeHelper.HitTest(listview, Mouse.GetPosition(listview));
            int count = VisualTreeHelper.GetChildrenCount(listview);
            ItemsPresenter item = (ItemsPresenter)VisualTreeHelper.GetChild(listview, count - 1);
            //ListBoxItem rect = result.VisualHit as ListBoxItem;
            if (item != null)
            {
                object source = item.DataContext as object;
            }
        }

        public void OnDrop(object sender, MouseButtonEventArgs e)
        {
            if (!string.IsNullOrEmpty(DragDeviceSn))
            {
                ShowPriceInout = true;
            }
        }

        public void OnMouseEnter(object sender, MouseEventArgs e)
        {

        }

        
        #endregion

        #region Pagination
        private int _selectedUserPage = 1;
        public int SelectedUserPage
        {
            get { return _selectedUserPage; }
            set
            {
                _selectedUserPage = value;
                RaisePropertyChanged(() => SelectedUserPage);
            }
        }

        private int _selectedDevicePage = 1;
        public int SelectedDevicePage
        {
            get { return _selectedDevicePage; }
            set
            {
                _selectedUserPage = value;
                RaisePropertyChanged(() => SelectedDevicePage);
            }
        }

        private ObservableCollection<int> _userPager;
        public ObservableCollection<int> UserPager
        {
            get { return _userPager; }
            set
            {
                _userPager = value;
                RaisePropertyChanged(() => UserPager);
            }
        }

        private ObservableCollection<int> _devicePager;
        public ObservableCollection<int> DevicePager
        {
            get { return _devicePager; }
            set
            {
                _devicePager = value;
                RaisePropertyChanged(() => DevicePager);
            }
        }
        #endregion
    }
}
